#!/usr/bin/env python3

"""
Nagios plugin to check that our MIT users' Zephyr mirrors are running.

It must be run on a machine that is using the live database for the
Django ORM.
"""
import datetime
import os
import sys

sys.path.append('/home/zulip/deployments/current')
import scripts.lib.setup_path_on_import

import django
from django.utils.timezone import now as timezone_now

os.environ['DJANGO_SETTINGS_MODULE'] = "zproject.settings"
sys.path.append('/home/zulip/deployments/current')
sys.path.append('/home/zulip/deployments/current/zerver')

django.setup()

from zerver.models import UserActivity

if False:
    # See https://zulip.readthedocs.io/en/latest/testing/mypy.html#mypy-in-production-scripts
    from typing import Any, Dict, Set, Optional

states = {
    "OK": 0,
    "WARNING": 1,
    "CRITICAL": 2,
    "UNKNOWN": 3
}  # type: Dict[str, int]

def report(state, short_msg, too_old=None):
    # type: (str, str, Optional[Set[Any]]) -> None
    too_old_data = ""
    if too_old:
        too_old_data = "\nLast call to get_message for recently out of date mirrors:\n" + "\n".join(
            ["%16s: %s" % (user.user_profile.email,
                           user.last_visit.strftime("%Y-%m-%d %H:%M %Z")
                           ) for user in too_old]
        )
    print("%s: %s%s" % (state, short_msg, too_old_data))

    exit(states[state])

now = timezone_now()

all_users = UserActivity.objects.filter(query__in=["get_events", "/api/v1/events"],
                                        client__name="zephyr_mirror")
new_inactive_users = [user for user in all_users if user.last_visit <
                      now - datetime.timedelta(minutes=10)]
old_inactive_users = [user for user in new_inactive_users if user.last_visit <
                      now - datetime.timedelta(minutes=60)]
recently_inactive_users = set(new_inactive_users) - set(old_inactive_users)

if (len(recently_inactive_users) / float(len(old_inactive_users))) > .25:
    report("CRITICAL", "Many mirrors recently became inactive", recently_inactive_users)
else:
    report("OK", "Most mirrors that were recently active continue to be active")
